import React from 'react';
import {requireNativeComponent, findNodeHandle, UIManager, ActivityIndicator, View, StyleSheet} from 'react-native';
import PropTypes from 'prop-types';

const defaultIndicatorSize = 16;

class MyIJKPlayer extends React.Component {
    static MEDIA_ERROR_UNKNOWN = 1;
    static MEDIA_ERROR_SERVER_DIED = 100;
    static MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK = 200;
    static MEDIA_ERROR_IO = -1004;
    static MEDIA_ERROR_MALFORMED = -1007;
    static MEDIA_ERROR_UNSUPPORTED = -1010;
    static MEDIA_ERROR_TIMED_OUT = -110;
    static MEDIA_INFO_UNKNOWN = 1;
    static MEDIA_INFO_STARTED_AS_NEXT = 2;
    static MEDIA_INFO_VIDEO_RENDERING_START = 3;
    static MEDIA_INFO_VIDEO_TRACK_LAGGING = 700;
    static MEDIA_INFO_BUFFERING_START = 701;
    static MEDIA_INFO_BUFFERING_END = 702;
    static MEDIA_INFO_NETWORK_BANDWIDTH = 703;
    static MEDIA_INFO_BAD_INTERLEAVING = 800;
    static MEDIA_INFO_NOT_SEEKABLE = 801;
    static MEDIA_INFO_METADATA_UPDATE = 802;
    static MEDIA_INFO_TIMED_TEXT_ERROR = 900;
    static MEDIA_INFO_UNSUPPORTED_SUBTITLE = 901;
    static MEDIA_INFO_SUBTITLE_TIMED_OUT = 902;

    static MEDIA_INFO_VIDEO_ROTATION_CHANGED = 10001;
    static MEDIA_INFO_AUDIO_RENDERING_START = 10002;
    static MEDIA_INFO_AUDIO_DECODED_START = 10003;
    static MEDIA_INFO_VIDEO_DECODED_START = 10004;
    static MEDIA_INFO_OPEN_INPUT = 10005;
    static MEDIA_INFO_FIND_STREAM_INFO = 10006;
    static MEDIA_INFO_COMPONENT_OPEN = 10007;
    static MEDIA_INFO_VIDEO_SEEK_RENDERING_START = 10008;
    static MEDIA_INFO_AUDIO_SEEK_RENDERING_START = 10009;
    static MEDIA_INFO_MEDIA_ACCURATE_SEEK_COMPLETE = 10100;

    constructor(props) {
        super(props);
        this.state = {
            indicatorLeft: null,
            indicatorTop: null,
            showIndicator: true,
        };
    }

    componentDidMount(): void {
    }

    static getDerivedStateFromProps(props, state) {
        const {style: {width, height}} = props;
        const indicatorLeft = width / 2 - defaultIndicatorSize / 2;
        const indicatorTop = height / 2 - defaultIndicatorSize / 2;
        if (
            indicatorLeft !== state.indicatorLeft
            || indicatorTop !== state.indicatorTop
        ) {
            return {
                indicatorLeft,
                indicatorTop,
            };
        }
        return null;
    }

    _onReceiveRatioHW = ({nativeEvent: {ratioHW}}) => {
        if (this.ratioHW !== ratioHW && this.props.onReceiveRatioHW) {
            this.ratioHW = ratioHW;
            this.props.onReceiveRatioHW(ratioHW);
        }
    };

    _onReceiveDuration = ({nativeEvent: {duration}}) => {
        if (this.props.onReceiveDuration) {
            this.props.onReceiveDuration(duration);
        }
    };
    _onInfo = ({nativeEvent: {code}}) => {
        switch (code) {
            case MyIJKPlayer.MEDIA_INFO_BUFFERING_START:
                this.setState({showIndicator: true});
                break;
            case MyIJKPlayer.MEDIA_INFO_BUFFERING_END:
                this.setState({showIndicator: false});
                break;
            default:
                break;
        }
        if (this.props.onInfo) {
            this.props.onInfo(code);
        }
    };
    _onError = ({nativeEvent: {code}}) => {
        if (this.props.onError) {
            this.props.onError(code);
        }
    };
    _onPrepared = () => {
        if (this.props.onPrepared) {
            this.props.onPrepared();
        }
        this.setState({showIndicator: false});
    };
    _onProgressUpdate = ({nativeEvent: {progress}}) => {
        // console.log('IJKPlayer onProgressUpdate:',progress)
        const {onProgressUpdate: onProgressUpdate} = this.props;
        onProgressUpdate && onProgressUpdate(progress);
    };

    pause = () => {
        console.log('pause');
        UIManager.dispatchViewManagerCommand(
            findNodeHandle(this.ref),
            UIManager.getViewManagerConfig('IJKPlayer').Commands.pause,
            null,
        );
    };

    play = () => {
        console.log('play');
        UIManager.dispatchViewManagerCommand(
            findNodeHandle(this.ref),
            UIManager.getViewManagerConfig('IJKPlayer').Commands.play,
            null,
        );
    };
    stop = () => {
        console.log('stop');
        UIManager.dispatchViewManagerCommand(
            findNodeHandle(this.ref),
            UIManager.getViewManagerConfig('IJKPlayer').Commands.stop,
            null,
        );
    };

    seekTo = (progress) => {
        console.log('seekTo');
        UIManager.dispatchViewManagerCommand(
            findNodeHandle(this.ref),
            UIManager.getViewManagerConfig('IJKPlayer').Commands.seekTo,
            [progress],
        );
    };

    render(): React.ReactNode {
        const {indicatorLeft, indicatorTop, showIndicator} = this.state;
        return <View style={styles.container}>
            <IJKPlayer
                {...this.props}
                ref={ref => this.ref = ref}
                onReceiveRatioHW={this._onReceiveRatioHW}
                onReceiveDuration={this._onReceiveDuration}
                onInfo={this._onInfo}
                onError={this._onError}
                onPrepared={this._onPrepared}
                onProgressUpdate={this._onProgressUpdate}
            />
            <ActivityIndicator
                style={{...styles.indicator, left: indicatorLeft, top: indicatorTop}}
                size={defaultIndicatorSize}
                animating={showIndicator}
            />
        </View>;
    }
}

const styles = StyleSheet.create({
    container: {
        position: 'relative',
    },
    indicator: {
        position: 'absolute',
    },

});

const IJKPlayer = requireNativeComponent('IJKPlayer', MyIJKPlayer);

export default MyIJKPlayer;
